package sk.hackcraft.util.simulation;

import sk.hackcraft.util.simulation.statistics.SimulationReport;

public abstract class Simulation
{
	private final long numberOfReplications;
	private final Replication replication;
	
	private SimulationController controller;
	
	private final long moduloCoefficient;
	private long replicationId;
	
	public Simulation(long numberOfReplications, Replication replication)
	{
		this.numberOfReplications = numberOfReplications;
		this.replication = replication;
		
		this.moduloCoefficient = numberOfReplications / 100;
	}
	
	public void setController(SimulationController controller)
	{
		this.controller = controller;
		this.replication.setController(controller);
	}
	
	protected SimulationController getController()
	{
		return controller;
	}
	
	public Replication getReplication()
	{
		return replication;
	}
	
	protected long getReplicationId()
	{
		return replicationId;
	}
	
	public void simulate()
	{
		boolean isStopped = controller != null ? controller.isStopped() : false;
		
		for(replicationId=1; replicationId<=numberOfReplications && !isStopped; replicationId++)
		{
			replication.simulate();
			
			updateStatistics();
			
			if(controller != null)
			{
				controller.reportSimulation(getResults());
				
				if(replicationId % moduloCoefficient == 0)
				{
					controller.setProgress((int) (replicationId /  moduloCoefficient));
				}
				
				isStopped = controller.isStopped();
			}
		}
		
		if(controller != null)
		{
			this.controller.finished();
		}
	}
	
	protected abstract void updateStatistics();
	
	public abstract SimulationReport getResults();
}
